/**
 * Created by Anard on 2017/4/17.
 */
let mysql = require('./mysql.js');
let publicDao = module.exports;

publicDao.c = {};
publicDao.c.table = '';
publicDao.c.wheres = [];
publicDao.c.args = [];
publicDao.c.pluck = '*';
publicDao.c.orders = [];
publicDao.c.group = '';
publicDao.c.limit = '';
publicDao.c.values = [];

publicDao.init = function () {
    publicDao.c = {};
    publicDao.c.table = '';
    publicDao.c.wheres = [];
    publicDao.c.args = [];
    publicDao.c.pluck = '*';
    publicDao.c.orders = [];
    publicDao.c.group = '';
    publicDao.c.limit = '';
    publicDao.c.values = [];

    return this;
};


publicDao.table = function (table) {
    publicDao.c.table = table;

    return this;
};

publicDao.pluck = function () {
    let ar = [];
    for (let i in arguments) {
        ar.push(arguments[i]);
    }
    publicDao.c.pluck = '`' + ar.join('`,`') + '`';

    return this;
};

publicDao.limit = function (num, start) {
    if (!start && start !== 0) {
        publicDao.c.limit = 'limit ' + num;
    } else {
        publicDao.c.limit = 'limit ' + start + ',' + num;
    }

    return this;
};

publicDao.wheres = function (field, type, value) {
    publicDao.c.wheres.push('`' + field + '` ' + type + ' ?');
    publicDao.c.args.push(value);

    return this;
};

publicDao.orders = function (field, type) {
    if (type === 0 || type == 'asc' || type == 'ASC') {
        publicDao.c.orders.push('`' + field + '` ASC');
    } else {
        publicDao.c.orders.push('`' + field + '` DESC');
    }

    return this;
};

publicDao.orderRand = function(){
    publicDao.c.orders.push('rand()');

    return this;
};

publicDao.group = function (field) {
    publicDao.c.group = 'GROUP BY `' + field + '`';

    return this;
};

publicDao.mixWheres = function () {
    if (publicDao.c.wheres.length > 0) {
        return publicDao.c.wheres.join(' AND ');
    } else {
        return 1;
    }
};

publicDao.mixOrders = function () {
    if (publicDao.c.orders.length > 0) {
        return 'ORDER BY ' + publicDao.c.orders.join(' , ');
    } else {
        return '';
    }
};

publicDao.get = function (cb) {
    let sql = "SELECT " + publicDao.c.pluck + " FROM `" + publicDao.c.table + "` WHERE " + publicDao.mixWheres() + " " + publicDao.mixOrders() + " " + publicDao.c.limit;
    let args = publicDao.c.args;

    publicDao.query(sql, args, cb);

    return this;
};

publicDao.count = function (cb) {
    let sql = "SELECT COUNT(" + publicDao.c.pluck + ") as `num` FROM `" + publicDao.c.table + "` WHERE " + publicDao.mixWheres();
    let args = publicDao.c.args;

    publicDao.query(sql, args, cb);

    return this;
};

publicDao.query = function (sql, args, cb) {
    //console.error(sql);
    //console.error(args);
    //console.warn(sql,args);
    if (typeof args === 'function') {
        cb = args;
        mysql.query(sql, function (err, res) {
            if (err !== null) {
                cb({code: err.code, message: err.message}, null);
            } else {
                //console.error(res);
                cb(null, res);
            }
        });
    } else {
        mysql.query(sql, args, function (err, res) {
            if (err !== null) {
                cb({code: err.code, message: err.message}, null);
            } else {
                //console.error(res);
                cb(null, res);
            }
        });
    }
};

publicDao.values = function (key, value) {
    publicDao.c.values.push({'key': key, 'value': value});

    return this;
};

publicDao.insert = function (cb) {
    let field = [];
    let value = [];
    let args = [];
    for (let i in publicDao.c.values) {
        let v = publicDao.c.values[i];
        field.push(v.key);
        value.push('?');
        args.push(v.value);
    }
    let sql = "INSERT INTO " + publicDao.c.table + " (" + field.join(',') + ") VALUES (" + value.join(',') + ")";
    console.error(sql);
    console.error(args);
    mysql.insert(sql, args, function (err, res) {
        if (err !== null) {
            cb({code: err.code, message: err.message}, null);
        } else {
            //console.error(res);
            cb(null, res);
        }
    });
};

publicDao.update = function (cb) {
    let value = [];
    let args = [];
    for (let i in publicDao.c.values) {
        let v = publicDao.c.values[i];
        value.push(v.key + '=?');
        args.push(v.value);
    }
    let sql = "UPDATE `" + publicDao.c.table + "` SET " + value.join(',') + " WHERE " + publicDao.mixWheres();
    args = args.concat(publicDao.c.args);
    //console.error(sql);
    //console.error(args);
    mysql.update(sql, args, function (err, res) {
        if (err !== null) {
            cb({code: err.code, message: err.message}, null);
        } else {
            //console.error(res);
            cb(null, res);
        }
    });
};

publicDao.delete = function (cb) {
    let sql = "DELETE FROM `" + publicDao.c.table + "` WHERE " + publicDao.mixWheres();
    let args = publicDao.c.args;
    //console.error(sql);
    //console.error(args);
    mysql.delete(sql, args, function (err, res) {
        if (err !== null) {
            cb({code: err.code, message: err.message}, null);
        } else {
            //console.error(res);
            cb(null, res);
        }
    });
};